package jdt.geom;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * The bounding triangle used for the delaunay triangulation
 * 
 * @author Shay
 * 
 */
public class BoundingTriangle {

	/* --- Data members --- */

	/** The maximum value of a coordinate in all the points of the triangulation */
	private double maxCoordinateValue;

	/* --- Ctors. --- */

	/**
	 * Construct an instance using the maximum coordinate value
	 * 
	 * @param maxCoordinateValue
	 *            The maximum coordinate value
	 */
	public BoundingTriangle(double maxCoordinateValue) {
		this.maxCoordinateValue = maxCoordinateValue;
	}

	/**
	 * The default constructor
	 */
	public BoundingTriangle() {
	}

	/* --- Public Methods --- */

	/**
	 * Update this bounding triangle with the argument point.
	 * 
	 * @param p
	 *            The point to update the bounding triangle with
	 */
	public void update(Point p) {
		double absX = Math.abs(p.getX());
		double absY = Math.abs(p.getY());
		double absMaxCoordinateValue = Math.max(absX, absY);

		if (absMaxCoordinateValue > maxCoordinateValue) {
			maxCoordinateValue = absMaxCoordinateValue;
		}
	}

	/**
	 * @return the points corresponds to this instance
	 */
	public List<Point> getPoints() {
		List<Point> points = new ArrayList<Point>(3);
		// The order of the points in the list is important
		points.add(new Point(3 * maxCoordinateValue, 0));
		points.add(new Point(0, 3 * maxCoordinateValue));
		points.add(new Point(-3 * maxCoordinateValue, -3 * maxCoordinateValue));
		return points;
	}

	/**
	 * @return the triangle of this instance
	 */
	public Triangle getTriangle() {
		List<Point> points = getPoints();
		return new Triangle(points.get(0), points.get(1), points.get(2));
	}

	/**
	 * Checks if the argument triangle has at least one overlapping vertex with
	 * the bounding triangle
	 * 
	 * @return True or false
	 */
	public boolean isRelated(Triangle triangle) {
		return getTriangle().isRelated(triangle);
	}

	/**
	 * Retain from the arguments points all vertices of this bounding triangle
	 * 
	 * @param points
	 *            THe points to check
	 * @return the set of vertices of the bounding triangle
	 */
	public Set<Point> retainRelatedPoint(Set<Point> points) {
		Set<Point> boundingPoints = new HashSet<Point>(getPoints());
		boundingPoints.retainAll(points);
		return boundingPoints;

	}

	/**
	 * Get the negative index of the argument. The indices are:<br>
	 * -1 = (3M, 0)<br>
	 * -2 = (0, 3M)<br>
	 * -2 = (-3M, -3M)
	 * 
	 * @param p
	 *            The point to get the index of
	 * @return the negative index, or zero if the point is not a vertex of the
	 *         bounding triangle
	 */
	public int getNegativeIndex(Point p) {
		return -1 * (getPoints().indexOf(p) + 1);
	}

	/* --- Access Methods --- */

	/**
	 * @return the maximum coordinate value
	 */
	public double getMaxCoordinateValue() {
		return maxCoordinateValue;
	}
}
